package org.mtmi.ui.controls.popups;

import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.mtmi.ui.M;
import org.mtmi.ui.controls.Slider;
import org.mtmi.ui.controls.listeners.ValueChangedListener;
import org.mtmi.ui.controls.listeners.ValueEvent;
import org.mtmi.ui.drawables.ColorDrawable;
import org.mtmi.ui.drawables.IDrawable;
import org.mtmi.ui.scenes.COLOR;
import org.mtmi.ui.scenes.Scene;

/**
 * A popup to choose a color.
 */
public class ColorPopup extends AbstractButtonPopup
  implements ValueChangedListener
{
    private Slider r,g,b, h,s,v;
    private ColorDrawable sample;
    private Rectangle r_sample;
    private RGB rgb;
    
	public ColorPopup(Scene scene, String title, int flags) {
		super( scene, title, flags );
		setRGB( new RGB( 128, 128, 128 ) );//default value
	}
	
	public RGB getRGB() { 
		return new RGB( rgb.red, rgb.green, rgb.blue );
	}
	
	public void setRGB( RGB c ) {
		rgb = new RGB( c.red, c.green, c.blue );
		if( r!=null ) {
			r.setValue( rgb.red );
			g.setValue( rgb.green );
			b.setValue( rgb.blue );
			updateSample();
		}
	}
	
	private void updateHSB() {
		float hsb[] = rgb.getHSB();
		h.removeValueChangedListener( this );
		s.removeValueChangedListener( this );
		v.removeValueChangedListener( this );
		h.setValue( (int)(10*hsb[0]) );
		s.setValue( (int)(100*hsb[1]) );
		v.setValue( (int)(100*hsb[2]) );
		h.addValueChangedListener( this );
		s.addValueChangedListener( this );
		v.addValueChangedListener( this );
	}

	private RGB fromHSB() {
		float vh = h.getValue()/10f;
		float vs = s.getValue()/100f;
		float vb = v.getValue()/100f;
		return new RGB( vh, vs, vb );
	}
	
	private static class SimpleSlider extends Slider
	{
		public SimpleSlider( Scene scene, boolean isHoriz, int valCurrent, int valMin, int valMax, int flags ) {
			super(scene, isHoriz, valCurrent, valMin, valMax, flags);
			thumbLength = 50;
			paintThumbGrip=false;
		}
		@Override
		protected void paintBackground(GC gc) {}
	}
	
	@Override
	public Rectangle createContents( Scene _scene )
	{
		r = new SimpleSlider( _scene, true, 0,0, 255, getFlags() & M.SCENE_EDITOR_CONTROL );
		g = new SimpleSlider( _scene, true, 0,0, 255, getFlags() & M.SCENE_EDITOR_CONTROL );
		b = new SimpleSlider( _scene, true, 0,0, 255, getFlags() & M.SCENE_EDITOR_CONTROL );
		h = new SimpleSlider( _scene, true, 0,0, 3600, getFlags() & M.SCENE_EDITOR_CONTROL );
		s = new SimpleSlider( _scene, true, 0,0, 100, getFlags() & M.SCENE_EDITOR_CONTROL );
		v = new SimpleSlider( _scene, true, 0,0, 100, getFlags() & M.SCENE_EDITOR_CONTROL );

		r.addValueChangedListener( this );
		g.addValueChangedListener( this );
		b.addValueChangedListener( this );
		h.addValueChangedListener( this );
		s.addValueChangedListener( this );
		v.addValueChangedListener( this );
		
//TODO:old:		int sh = r.getSize().y;
//TODO:old:		int w = r.getSize().x;
		int sh = 50;
		int w = 300 ;
		int m = 10;
		int h1 = sh*6+5*m;
		
		int x = (_scene.getSize().x-w)/2;
		int y = (_scene.getSize().y-h1)/2;
		
		int ty = y;
		r.setBounds( x, ty, w, sh );
		ty += sh+m;
		g.setBounds( x, ty, w, sh );
		ty += sh+m;
		b.setBounds( x, ty, w, sh );
		ty += sh+m;
		h.setBounds( x, ty, w, sh );
		ty += sh+m;
		s.setBounds( x, ty, w, sh );
		ty += sh+m;
		v.setBounds( x, ty, w, sh );
		
		r.setThumbColor( COLOR.red );
		g.setThumbColor( COLOR.green );
		b.setThumbColor( COLOR.blue );
		
		sample = new ColorDrawable( new Color( getScene().getDisplay(), 0,0,0 ), false );
		int sz = Math.max( 50, h1/2 );
		r_sample = new Rectangle( x+w+m, y+(h1-sz)/2, sz, sz );
		w += m+sz;
		h1 = Math.max( h1, sz );
		
		if( rgb!=null ) {
			r.setValue( rgb.red );
			g.setValue( rgb.green );
			b.setValue( rgb.blue );
			updateHSB();
			sample.setColor( new Color( getScene().getDisplay(), rgb ) );
		}
		
		return new Rectangle( x, y, w, h1 );
	}
	
	@Override
	public void paintContent(GC gc, int width, int height) {
		super.paintContent(gc, width, height);
		sample.paint( gc, r_sample.x, r_sample.y, r_sample.width, r_sample.height, IDrawable.NORMAL );
	}

	private void updateSample() {
		sample.getColor().dispose();
		sample.setColor( new Color( getScene().getDisplay(), rgb ) );
		getScene().redraw( r_sample.x, r_sample.y, r_sample.width, r_sample.height, true );
	}
	
	@Override
	protected void terminate(int id) {
		sample.getColor().dispose();
		r.dispose();
		g.dispose();
		b.dispose();
		h.dispose();
		s.dispose();
		v.dispose();
		super.terminate(id);
	}

	@Override
	public void valueChanged(ValueEvent event) {
		Object src = event.control;
		if( src == r ) {
			rgb.red = event.newValue;
			updateHSB();
			updateSample();
		}
		else if( src == g ) {
			rgb.green = event.newValue;
			updateHSB();
			updateSample();
		}
		else if( src == b ) {
			rgb.blue = event.newValue;
			updateHSB();
			updateSample();
		}
		else if( src == h || src == s || src == v ) {
			rgb = fromHSB();
			r.removeValueChangedListener( this );
			g.removeValueChangedListener( this );
			b.removeValueChangedListener( this );
			r.setValue( rgb.red );
			g.setValue( rgb.green );
			b.setValue( rgb.blue );
			r.addValueChangedListener( this );
			g.addValueChangedListener( this );
			b.addValueChangedListener( this );
			updateSample();
		}
	}
}
